home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: news.sprintlink.net!eskimo!scs
- From: scs@eskimo.com (Steve Summit)
- Subject: Re: realloc question
- X-Nntp-Posting-Host: eskimo.com
- Message-ID: <DM5tEn.BFo@eskimo.com>
- Sender: news@eskimo.com (News User Id)
- Organization: schmorganization
- References: <4ehi4b$qfo@news.texas.net>
- Date: Fri, 2 Feb 1996 17:47:10 GMT
-
- In article <4ehi4b$qfo@news.texas.net>, gcherer@millenium.texas.net writes:
- > Whether i am on my old 286 with 1 meg, or on my 486 with 8 meg of ram, i
- > get the same result when i do a realloc on about the 50th iteration.( its
- > on an array of pointers). but, when i compile and run the same program on
- > a unix box (with beacoups more memory) it runs with no probs.
- >...
- > x++;
- > ptr=(struct sumthin**) realloc(ptr,(x+1) * sizeof(struct sumthin));
- > ptr[x]=(struct sumthin*) calloc(1,sizeof(struct sumthin));
- >
- > Any ideas?? Sure preeeeeciate 'em. TIA
-
- There are three possible problems that I can see:
-
- 1. You're simply running out of memory. (You already
- thought of that one.)
-
- 2. The typo you made in the code fragment above also appears
- in the code you're running, and you're allocating much
- more memory than you need for the struct sumthin pointers,
- and wasting (not using) most of it. The second line
- should read
-
- ptr = (struct sumthin **)realloc(ptr,
- (x+1) * sizeof(struct sumthin *));
-
- (This is easy to spot, if you remember the rule that
- there should always be one more * in the cast than in the
- sizeof. On the other hand, the explicit cast isn't
- really recommended any more.)
-
- 3. You're fragmenting memory, so that although there's an
- amount of total free memory available which is greater
- than or equal to your request, it's not contiguous and
- no one piece is big enough to satisfy your request.
-
- This is most likely your problem, because the calling
- pattern you've shown turns out to fragment memory in the
- worst possible way, if malloc and realloc are using the
- obvious "first fit" allocation. I've sent you a longer
- description in e-mail (which anyone else is welcome to on
- request), but basically what happens is that the array of
- struct sumthin pointers leapfrogs through memory, leaving
- a trail of successively larger holes behind it, each
- guarded on either side by a block of struct sumthin which
- you don't free or reallocate, and each too small for the
- larger and larger arrays of struct sumthin pointers you
- keep wanting.
-
- There are several ways to work around this last problem. You can
- use a version of malloc that doesn't use such a simpleminded
- first-fit strategy, and which therefore doesn't fragment memory
- so badly in the face of this calling pattern. (It's likely that
- the Unix machine you tried the program on, besides having more
- memory, also used a different malloc algorithm, since the simple
- first-fit algorithms perform very badly in a virtual memory
- environment anyway.) You can dig into your existing malloc and
- tweak its search behavior on the fly (I've occasionally done
- this), but of course this is completely nonportable and ties you
- to a particular malloc implementation and isn't generally
- recommended.
-
- Finally, you can change your memory allocation pattern. One easy
- fix (which I've used to success when I've had exactly this
- problem, on my poor old PDP-11 with 64K) is to grow your array of
- struct sumthin pointers in chunks of 10 or 50 at a time, instead
- of 1 at a time. (In this case, you have to keep track of two
- counts, one of how many pointers you've allocated and one of how
- many of them you're using). You may still fragment memory in
- this case, but not nearly so quickly or so badly. Yet another
- solution would be to use a linked list, so that you wouldn't need
- contiguous arrays of pointers at all.
-
- Steve Summit
- scs@eskimo.com
-